use super::simd_advanced::{SimdResult, SimdError};

#[derive(Debug, Clone)]
pub struct CciResult {
    pub cci: Vec<f64>,
    pub typical_prices: Vec<f64>,
    pub sma: Vec<f64>,
    pub mean_deviation: Vec<f64>,
}

impl CciResult {
    pub fn with_capacity(size: usize) -> Self {
        Self {
            cci: Vec::with_capacity(size),
            typical_prices: Vec::with_capacity(size),
            sma: Vec::with_capacity(size),
            mean_deviation: Vec::with_capacity(size),
        }
    }

    pub fn validate(&self) -> SimdResult<()> {
        let len = self.cci.len();
        if self.typical_prices.len() != len || 
           self.sma.len() != len || 
           self.mean_deviation.len() != len {
            return Err(SimdError::ValidationError(
                "All CCI result vectors must have the same length".to_string()
            ));
        }
        Ok(())
    }
}

pub fn compute_cci(
    high: &[f64],
    low: &[f64],
    close: &[f64],
    period: usize,
) -> SimdResult<CciResult> {
    if high.len() != low.len() || high.len() != close.len() {
        return Err(SimdError::InvalidInputLength(
            "High, low and close arrays must have the same length".to_string()
        ));
    }

    let len = high.len();
    let mut result = CciResult::with_capacity(len);

    // 计算典型价格 (TP = (High + Low + Close) / 3)
    for i in 0..len {
        result.typical_prices.push((high[i] + low[i] + close[i]) / 3.0);
    }

    // 计算移动平均 (SMA)
    for i in 0..len {
        if i < period - 1 {
            result.sma.push(f64::NAN);
            continue;
        }

        let sum: f64 = result.typical_prices[i - period + 1..=i].iter().sum();
        result.sma.push(sum / period as f64);
    }

    // 计算平均偏差
    for i in 0..len {
        if i < period - 1 {
            result.mean_deviation.push(f64::NAN);
            continue;
        }

        let sma = result.sma[i];
        let mut sum_deviation = 0.0;
        for j in i - period + 1..=i {
            sum_deviation += (result.typical_prices[j] - sma).abs();
        }
        result.mean_deviation.push(sum_deviation / period as f64);
    }

    // 计算CCI ((TP - SMA) / (0.015 * MD))
    for i in 0..len {
        if i < period - 1 {
            result.cci.push(f64::NAN);
            continue;
        }

        let md = result.mean_deviation[i];
        if md.abs() < 1e-10 {
            result.cci.push(0.0);
            continue;
        }

        let cci = (result.typical_prices[i] - result.sma[i]) / (0.015 * md);
        result.cci.push(cci);
    }

    result.validate()?;
    Ok(result)
}